package at.ac.tuwien.lsds.schedule.strategy;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import at.ac.tuwien.lsds.model.Application;
import at.ac.tuwien.lsds.model.PhysicalMachine;
import at.ac.tuwien.lsds.util.ProcessSummaryOutputRow;
import at.ac.tuwien.lsds.util.SchedulerOutputRow;
import at.ac.tuwien.lsds.util.Settings;

public abstract class ScheduleStrategyImpl implements ScheduleStrategy{
	protected List<PhysicalMachine> pms;
	protected List<Application>     queue;
	
	// Total sums
	protected Integer totalPms = 0;
	protected Integer totalVms = 0;
	protected Integer totalDuration = 0;
	protected Float   totalPowerConsumption = 0f;
	protected Integer totalInSourced = 0;
	protected Integer totalOutSourced = 0;
	
	@Override
	public Integer getRunningPMCount(){
		return pms.size();
	}
	
	@Override
	public Float getCurrentPowerConsumption() {
		Float currentPowerConsumption = 0F;
		
		for (PhysicalMachine pm : pms){
			currentPowerConsumption += pm.getPowerConsumtion();
		}
		
		return currentPowerConsumption;
	}
	
	@Override
	public ProcessSummaryOutputRow getProcessSummaryOutputRow() {
		return new ProcessSummaryOutputRow(
				Settings.getScheduler().toString(), 
				Settings.getScenario().toString(),
				totalPms,
				totalVms, 
				totalDuration,
				totalPowerConsumption,
				totalInSourced,
				totalOutSourced);
	}
	
	@Override
	public SchedulerOutputRow getCurrentConsumptionOutputRow(Integer currentTimestamp) {
		Iterator<PhysicalMachine> iterator = null;
		PhysicalMachine pm = null;
		SchedulerOutputRow sor = null;
		
		Integer currentHddConsumption = 0;
		Integer currentRamConsumption = 0;
		Integer currentCpuConsumption = 0;
		Integer currentRunningVms = 0;
		Float currentPowerConsumption = 0F;
		
		iterator = pms.iterator();
		
		while(iterator.hasNext()){
			pm = iterator.next();
			
			currentHddConsumption += pm.getHddInUse();
			currentRamConsumption += pm.getRamInUse();
			currentCpuConsumption += pm.getCpuInUse();
			currentRunningVms += pm.getRunningVMCount();
			currentPowerConsumption += pm.getPowerConsumtion();
		}
		
		sor = new SchedulerOutputRow(
			currentTimestamp,
			currentRamConsumption,
			currentCpuConsumption, 
			currentHddConsumption,
			pms.size(),
			currentRunningVms,
			currentPowerConsumption,
			0, // Insourced // TODO
			0  // Outsourced // TODO
		);
		
		return sor;
	}
	
	@Override
	public void increaseRunningTime(){
		for (PhysicalMachine pm : new ArrayList<PhysicalMachine>(pms)) {
			pm.increaseRunningTime();
		}
		
		// Calculate totals like hdd, cpu and ram here (except pm and vm counter)
		totalPowerConsumption += getCurrentPowerConsumption();
		totalDuration += 1;
		
		runningTimeIncreased();
	}
	
	@Override
	public void runningTimeIncreased(){};
}
